package com.xpec.net.xnetty.cihper;

import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;

import com.xpec.c4.net.handler.ConsolidatingAutoFlusher;
import com.xpec.cipher.CipherConnectionConstant;
import com.xpec.cipher.CipherConnectionStatus;
import com.xpec.cipher.handler.ServerFinishHandler;
import com.xpec.cipher.handler.ServerHandShakeCreateKeyHandler;
import com.xpec.cipher.tals.TalsConstance;

public class ServerCipherChannelHandler extends BaseCipherChannelHandler
{
	
	private static final Log log = LogFactory.getLog(ServerCipherChannelHandler.class);
	
	// 初始化handlers，添加所有状态对应的Hander
	static
	{
		//現在的流程
		handlers.put(CipherConnectionStatus.HAND_SHAKE, new ServerHandShakeCreateKeyHandler());
		handlers.put(CipherConnectionStatus.FINISH, new ServerFinishHandler());
		
		/*原C4流程
		handlers.put(CipherConnectionStatus.HAND_SHAKE, new ServerHandShakeHandler());
		handlers.put(CipherConnectionStatus.RECEIVE_PRE_MASTER, new ServerPreMasterHandler());
		handlers.put(CipherConnectionStatus.CHANGE_CIPHER, new ServerChangeCipherHandler());
		handlers.put(CipherConnectionStatus.FINISH, new ServerFinishHandler());
		*/
	}

	public ServerCipherChannelHandler(){
		setConnectionStatus(CipherConnectionStatus.HAND_SHAKE);
		attributes[CipherConnectionConstant.PARA_KEY_DECRYPT_COUNT] = new AtomicInteger(1);
		attributes[CipherConnectionConstant.PARA_KEY_ENCRYPT_COUNT] = new AtomicInteger(1);
		
		/// server 只採用幾 bytes 的 MAC 結果來驗證和送出, 此值會在握手階段傳給 client
		attributes[CipherConnectionConstant.PARA_KEY_MAC_SIZE] = TalsConstance.HMAC_SIZE;
	}
	
	@Override
	public void addOtherHandler(Channel channel)
	{
		ChannelPipeline p = channel.getPipeline();
		p.addFirst(ConsolidatingAutoFlusher.class.getSimpleName(), new ConsolidatingAutoFlusher());
	}	

	@Override
	public void operationComplete(ChannelFuture channelfuture) throws Exception
	{
		int status = getConnectionStatus();
		log.info("Cipher status:" + status);
		if (status == CipherConnectionStatus.HAND_SHAKE)
		{
			log.info("Cipher change status:" + status + " --> " + CipherConnectionStatus.FINISH);
			this.saveParameter(CipherConnectionConstant.PARA_KEY_STATUS,
				CipherConnectionStatus.FINISH);
		}
		
		/*原C4流程
		int status = getConnectionStatus();
		
		log.info("Cipher status:" + status);

		if (status == CipherConnectionStatus.HAND_SHAKE)
		{
			log.info("Cipher change status:" + status + " --> " + CipherConnectionStatus.RECEIVE_PRE_MASTER);
			this.saveParameter(CipherConnectionConstant.PARA_KEY_STATUS,
				CipherConnectionStatus.RECEIVE_PRE_MASTER);

		}
		if (status == CipherConnectionStatus.CHANGE_CIPHER)
		{
			log.info("Cipher change status:" + status + " --> " + CipherConnectionStatus.FINISH);

			this.saveParameter(CipherConnectionConstant.PARA_KEY_STATUS,
				CipherConnectionStatus.FINISH);

			this.addOtherHandler(channelfuture.getChannel());
		}*/
	}
}
